#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "n2base.h"
#include "n2x86asm.h"

#define ERROR_BASE_NUM              512
TN2StringPool* TAsxErrorList::pool = NULL;
TAsxErrorList errlist;

TAsxErrorList* AsxGetErrorList()
{
    return &errlist;
}

TAsxErrorList::TAsxErrorList()
{
    if (pool == NULL) {
        pool = new TN2StringPool(256*1024);
        if (pool == NULL)
            throw AsxEx_NoMemory;
    }
    alloc_cnt = ERROR_BASE_NUM;
    errs = new TAsxErrorText[alloc_cnt];
    if (errs == NULL)
        throw AsxEx_NoMemory;
    err_cnt = 0;
    base = ERROR_BASE_NUM;
}

TAsxErrorList::~TAsxErrorList()
{
    if (errs)
        delete[] errs;
    if (pool)
        delete pool;
    alloc_cnt = 0;
    err_cnt = 0;
    base = 0;
}

void TAsxErrorList::IncAllocSize()
{
    TAsxErrorText * newPtr;
    size_t newAllocCnt;
    size_t i;
    newAllocCnt = alloc_cnt + base;
    newPtr = new TAsxErrorText[newAllocCnt];
    if (newPtr == NULL)
        throw AsxEx_NoMemory;
    for (i = 0; i < alloc_cnt; i++) {
        newPtr[i].text = errs[i].text;
        newPtr[i].file = errs[i].file;
        newPtr[i].line = errs[i].line;
        newPtr[i].error_no = errs[i].error_no;
        newPtr[i].row = errs[i].row;
        newPtr[i].type = errs[i].type;
        newPtr[i].occur = errs[i].occur;
    }
    delete[] errs;
    errs = newPtr;
    alloc_cnt = newAllocCnt;
}

size_t TAsxErrorList::AddErrorWarnInfo(char type, char occur, const char* file, 
                     size_t line, size_t row, int err_no, const char* text, va_list va)
{
    char * prtbuff;
    const int PRT_BUFF_SIZE = 200*1024;
    TAsxErrorText * err;
    if (err_cnt >= alloc_cnt)
        IncAllocSize();
    err = &errs[err_cnt];
    
    err->type = type;
    err->occur = occur;
    err->line = line;
    err->row = row;
    err->error_no = err_no;
    if (file == NULL)
        file = "";
    if (err->occur == ERROR_OCCUR_ASM)
        err->file = pool->AddStr(file);
    else
        err->file = NULL;

    if (text == NULL)
        text = "";

    prtbuff = new char[PRT_BUFF_SIZE];
    if (prtbuff == NULL)
        throw AsxEx_NoMemory;

    vsnprintf(prtbuff, PRT_BUFF_SIZE-1, text, va);
    err->text = pool->AddStr(prtbuff);
    delete[] prtbuff;

    err_cnt++;
    return (err_cnt - 1);
}

size_t TAsxErrorList::AddWarnning(char occur, const char* file, 
                                       size_t line, size_t row, int err_no, const char* text, va_list va)
{
    return AddErrorWarnInfo(ERROR_TYPE_COMMON_WARN, occur, file, line, row, err_no, text, va);
}

size_t TAsxErrorList::AddError(char occur, const char* file, 
                                  size_t line, size_t row, int err_no, const char* text, va_list va)
{
    return AddErrorWarnInfo(ERROR_TYPE_COMMON_ERROR, occur, file, line, row, err_no, text, va);
}

size_t TAsxErrorList::AddFatalError(char occur, const char* file, 
                               size_t line, size_t row, int err_no, const char* text, va_list va)
{
    return AddErrorWarnInfo(ERROR_TYPE_FATAL_ERROR, occur, file, line, row, err_no, text, va);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void AsxCmdLineFatalError(int err_no, const char* format, ...)
{

}

void AsxCmdLineError(int err_no, const char* format, ...)
{

}

void AsxCmdLineWarn(int err_no, const char* format, ...)
{

}

void AsxIOFatalError(int err_no, const char* format, ...)
{

}

void AsxIOError(int err_no, const char* format, ...)
{

}

void AsxIOWarn(int err_no, const char* format, ...)
{

}

void AsxAsmFatalError(int err_no, size_t line, size_t row, const char* fname, const char* format, ...)
{


}

void AsxAsmError(int err_no, size_t line, size_t row, const char* fname, const char* format, ...)
{


}

void AsxAsmWarn(int err_no, size_t line, size_t row, const char* fname, const char* format, ...)
{


}


